﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//技能的对象
public class SkillObject
{
    public SkillDatabase TableData;//技能静态数据
    public SkillLogicBase Logic;//技能逻辑(动态数据)
}
//技能释放的阶段
public enum SkillStage 
{
    None=0,//没有施法
    Assist=1,//技能辅助阶段
    Casting=2,//施法阶段
}

//技能数据（静态部分）
public class SkillMgr 
{
    Creature _owner;
    List<SkillObject> _allSkill = new List<SkillObject>();
    List<int> skillIDList = new List<int>();
    //SkillLogicBase _skillLogic;
    SkillCaster _skillCaster=new SkillCaster();
    CastSkillAssist _castSkillAssist = new CastSkillAssist();
    SkillStage _skillStage = SkillStage.None;
    public Action<Creature> AutoSelectCallback;

    public bool IsCastingSkill { get { return _skillCaster.IsCasting; } }

    public bool IsAssistOrCastingSkill { get { return _skillStage == SkillStage.Assist || _skillStage == SkillStage.Casting; } }

    public void Init(Creature owner)
    {
        _owner = owner;
        _skillCaster.Init(_owner,OnSkillFinish);
        _castSkillAssist.Init(_owner);
        
        skillIDList = _owner.TableData.SkillList;
     
        //初始化技能
        for (int i = 0; i < GameSetting.MaxSkillNum; ++i)
        {
            var skillid = skillIDList[i];

            var skillObj = new SkillObject();

            skillObj.TableData = SkillTable.GetInstance()[skillid];
            if (skillObj.TableData == null)
            {
                Debug.LogError("技能初始化失败，未找到技能，id:" + skillid);
            }
            //根据字段反射生成类
            skillObj.Logic = typeof(SkillLogicBase).Assembly.CreateInstance(skillObj.TableData.ScriptType) as SkillLogicBase;
            if (skillObj.Logic == null)
            {
                Debug.LogError("未找到技能逻辑" + skillObj.TableData.ScriptType);
                continue;
            }
            skillObj.Logic.Init(_owner,skillObj.TableData);

            //暂时的，最终要读表
            _allSkill.Add(skillObj);
        }
    }

    private void OnSkillFinish()
    {
        _skillStage = SkillStage.None;
    }

    public void TryCastSkill(int index)
    {
        //Debug.Log(index);
        if (_skillCaster.IsCasting) { return; }
        //找到技能
        var skillObj = getSkillObject(index);
        if (skillObj == null)
        {
            Debug.LogError("TryCastSkill 未找到技能对象,索引号:"+index);
            return;
        }
        //CD
        if (skillObj.Logic.IsInCD) { return; }
        //需要目标，才检查目标的有效性(需要目标 & 有目标& 目标可被攻击)
        if (skillObj.TableData.CastRange > 0)
        {
            if (_owner.CurTarget == null)
            {
                var selectTarget=_castSkillAssist.SelectEnemy();
                if (selectTarget != null)
                {
                    Util.SafeCall(AutoSelectCallback, selectTarget);
                    _owner.CurTarget = selectTarget;
                }
                
            }
            //技能目标
            if (_owner.CurTarget == null) { return; }
            //目标是否能被攻击
            if (!_owner.CurTarget.CanBeAttack(_owner)) { return; }
            //施法范围判断
            var dis = Util.Distance2_5D(_owner.transform.position, _owner.CurTarget.transform.position);

            if (dis > skillObj.TableData.CastRange)
            {
                //Debug.Log("距离过远" + dis + "," + skillObj.TableData.CastRange);
                //技能进入辅助阶段
                _skillStage = SkillStage.Assist;
                _owner.TranceTo(_owner.CurTarget, skillObj.TableData.CastRange, () => onAssistFinish(skillObj.Logic));
                return;
            }
        }

        //CD

        //正在释放技能时，不能再放技能

        //开始放技能
        CastSkill(skillObj.Logic);
        
    }
    private void onAssistFinish(SkillLogicBase logic)
    {
        _skillStage = SkillStage.Casting;
        CastSkill(logic);
    }
    private void SafeCall()
    {
        if (AutoSelectCallback != null)
        {
            AutoSelectCallback(_owner.CurTarget);
        }
    }

    private void CastSkill(SkillLogicBase logic)
    {
        _owner.StopMove();
        _skillCaster.CastSkill(logic,_owner.CurTarget);
    }
   
    private SkillObject getSkillObject(int index)
    {
        return _allSkill[index - 1];
    }
    internal float getSkillCDPercent(int index)
    {
        var skillObject = getSkillObject(index);
        if (skillObject == null) { return 1; }
        //Debug.Log(skillObject.Logic.LeftCD / skillObject.Logic.MaxCD);
        return skillObject.Logic.LeftCD/skillObject.Logic.MaxCD;
    }
    internal void Loop()
    {
        //_skillLogic.Loop();
        _skillCaster.Loop();
    }

   
}
